package packLigaDeFutbol;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Random;

public class GestorUsuarios {

	private static GestorUsuarios miGestor;

	/** Constructor
	 * 	Autor: Andoni Serrano
	 */
	private GestorUsuarios(){}

	/** getInstance
	 * Autor: Andoni Serrano
	 * Comprobamos que haya instancia del gestor y sino la creamos
	 *  
	 * @return Devuelve el Gestor para su uso
	 */
	public static GestorUsuarios getInstance(){ 

		if (miGestor == null){
			miGestor = new GestorUsuarios();
		}
		return miGestor; 
	}

	/** autenticarUsuario
	 * Autor: Andoni Serrano
	 * Comprueba que los datos son correctos,
	 * lo guarda en el sistema y devuelve true.
	 *  
	 * @param pUsu		Nombre del usuario.
	 * @param pPasswd	Password del usuario.
	 * @return			Devolvemos true si es correcto.
	 */
	public boolean autenticarUsuario(String pUsu, String pPasswd){
		//Aqui no seria bueno devolver el idEquipo o idArbitro o idAdmin si es correcto o null si es falso?
		boolean ret = false;
		String strSQL;

		try {

			strSQL = "SELECT idUsuario, idtipousuario FROM usuarios " +
					"WHERE nombre='" + pUsu + "' " +
					"AND pwd='"+ calcularMD5(pPasswd) +"'";

			ResultSet rs = Principal.BBDD.consulta(strSQL);

			if(rs.next()){
				Principal.idUsu = rs.getInt("idUsuario");
				Principal.tipoUsu = rs.getInt("idtipousuario");
				ret = true;
			}else{
				Principal.idUsu = 0;
				Principal.tipoUsu = 0;
			}

		} catch (SQLException ex) {

			System.out.println("SQLException: " + ex.getMessage());
			System.out.println("SQLState: " + ex.getSQLState());
			System.out.println("VendorError: " + ex.getErrorCode());

		}

		return ret;
	}

	/** usuarioValido
	 * Autor: Andoni Serrano
	 * Comprueba que los datos son correctos,
	 *  
	 * @param pUsu		Nombre del usuario.
	 * @param pPasswd	Password del usuario.
	 * @return			Devolvemos true si es valido.
	 */
	public boolean usuarioValido(String pUsu, String pPasswd){
		boolean ret = false;
		String strSQL;

		try {

			strSQL = "SELECT * FROM usuarios " +
					"WHERE nombre='" + pUsu + "' " +
					"AND pwd='"+ calcularMD5(pPasswd) +"'";

			ResultSet rs = Principal.BBDD.consulta(strSQL);

			if(rs.next()){
				ret = true;
			}

		} catch (SQLException ex) {

			System.out.println("SQLException: " + ex.getMessage());
			System.out.println("SQLState: " + ex.getSQLState());
			System.out.println("VendorError: " + ex.getErrorCode());

		}

		return ret;
	}

	/**	recuperarPasswd
	 * Autor: Andoni Serrano
	 * Envia un email al usuario desde la clase Mailer para recuperar su password
	 *  
	 * @param usuario	Nombre del usuario
	 */
	public boolean recuperarPasswd(String usuario, String pMail){
		boolean ret = false;
		String nuevaPasswd = generarPWD(8);
		String strSQL = "SELECT nombre FROM usuarios " +
				"WHERE nombre='"+ usuario +"' " +
				"AND email='" + pMail +"'";

		try {
			ResultSet rs = Principal.BBDD.consulta(strSQL);

			if (rs.next()){

				String body = "Su nueva contrase\u00F1a es: " + nuevaPasswd;
				if(Mailer.enviarMail(new String[]{pMail}, "Recuperaci\u00F3n de contrase\u00F1a", body)){
					strSQL = "UPDATE usuarios " +
							"SET pwd='"+ calcularMD5(nuevaPasswd) +"'" + 
							"WHERE nombre='" + usuario + "'";
					Principal.BBDD.actualizar(strSQL);
					ret = true;
				}
			}

		} catch (SQLException ex) {
			System.out.println("SQLException: " + ex.getMessage());
			System.out.println("SQLState: " + ex.getSQLState());
			System.out.println("VendorError: " + ex.getErrorCode());
		}
		return ret;
	}

	/**	cambiarPwd
	 * Autor: Andoni Serrano
	 * Cambia el password del usuario
	 *  
	 * @param pUsu		Nombre del usuario
	 * @param pPwd		Password ACTUAL del usuario
	 * @param pNuevoPwd	NUEVO password del usuario
	 * @return
	 */
	public boolean cambiarPwd(String pUsu, String pOldPwd, String pNuevoPwd){
		boolean ret = true;
		String strSQL;

		try {
			strSQL = "UPDATE usuarios " +
					"SET pwd='"+ calcularMD5(pNuevoPwd) + "' " +
					"WHERE nombre='" + pUsu + "' " +
					"AND pwd='"+ calcularMD5(pOldPwd) + "'";

			Principal.BBDD.actualizar(strSQL);

		} catch (SQLException ex) {
			System.out.println("SQLException: " + ex.getMessage());
			System.out.println("SQLState: " + ex.getSQLState());
			System.out.println("VendorError: " + ex.getErrorCode());
			ret = false;
		}
		return ret;
	}

	/** calcularMD5
	 * Autor: Andoni Serrano
	 * Calcula el MD5 de un string para guardarlo en la base de datos.
	 * 
	 * @param pass	texto que se quiere codificar
	 * @return		MD5 del texto
	 */
	public static String calcularMD5(String pass) {
		MessageDigest m;
		byte[] data;
		BigInteger i = null;
		try {
			m = MessageDigest.getInstance("MD5");
			data = pass.getBytes(); 
			m.update(data,0,data.length);
			i = new BigInteger(1,m.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return String.format("%1$032X", i);
	}

	/** generarPWD
	 * Autor: Andoni Serrano
	 * Funcion que devuelve un string aleatorio
	 * generado a partir de los carateres de la 
	 * variable 'dic'
	 * 
	 * @param pLongitud	Longitud del nuevo password.
	 * @return Devolvemos el password generado.
	 */
	private String generarPWD(int pLongitud){

		String dic = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
		char[] nuevoPass = new char[pLongitud];
		Random rnd = new Random();
		String ret;
		for(int i=0; i<pLongitud; i++){

			nuevoPass[i] = dic.charAt(rnd.nextInt(dic.length()));
		}
		ret = new String(nuevoPass);
		return ret;

	}


	/**
	 * @author Asier
	 * 
	 * @param pIdUsu
	 * @param tipo
	 * @return
	 */
	public static int idAsociada(int pIdUsu, int tipo) {
		String str = "";
		int result = -1;
		switch(tipo) {
		case 2: str = "SELECT idEquipo FROM equipo WHERE idUsuario = " + pIdUsu + ";";
		break;
		case 3: str = "SELECT idArbitro FROM arbitro WHERE idUsuario = " + pIdUsu + ";";
		break;
		default:break;
		}
		try{
			ResultSet rs = Principal.BBDD.consulta(str);
			if(rs.next()) {
				result = rs.getInt(1);
			}
		}catch(SQLException e) {
			e.printStackTrace();
		}
		System.out.println(result);
		return result;
	}

	/**
	 * @author Bego
	 * @param pUsu
	 * @param pPwd
	 * @param pEmail
	 * @return
	 */
	public int crearUsuario(String pUsu, String pPwd, String pEmail) {
		int res = -1;
		String strSQL = "INSERT INTO usuarios(nombre, pwd, email, idTipoUsuario) " + 
				"VALUES ('" + 
				pUsu + "', '" +
				pPwd + "', '" +
				pEmail + "'," +
				"3" +
				");";
		try {	
			res = Principal.BBDD.ultimoID(strSQL);
		}
		catch(SQLException e) {
			e.printStackTrace();
		}
		return res;
	}

	/**
	 * @author Bego
	 * @param idUsuario
	 */
	public void eliminarUsuario(int idUsuario) {
		String strSQL = "DELETE FROM arbitro WHERE idArbitro = " + idUsuario;
		try {
			Principal.BBDD.borrar(strSQL);
		} catch (SQLException ex) {
			System.out.println("SQLException: " + ex.getMessage());
			System.out.println("SQLState: " + ex.getSQLState());
			System.out.println("VendorError: " + ex.getErrorCode());
		}
	}

	/**
	 * @author Bego
	 * 
	 * @param idArbitro
	 * @param usuario
	 * @param correo
	 * @return
	 */
	public int modificarUsuarioDesdeArbitro(int idArbitro, String usuario,
			String correo) {
		int res = -1;
		String strSQL = "UPDATE usuarios, arbitro "
				+ "SET usuarios.nombre = '" + usuario +"'"
				+ ", usuarios.email='" + correo + "' "
				+ "WHERE usuarios.idUsuario = arbitro.idUsuario "
				+ "AND arbitro.idArbitro = " + idArbitro;
		try {
			res = Principal.BBDD.actualizar(strSQL);
		} catch (SQLException ex) {
			System.out.println("SQLException: " + ex.getMessage());
			System.out.println("SQLState: " + ex.getSQLState());
			System.out.println("VendorError: " + ex.getErrorCode());
		}

		return res;

	}

	/**
	 * @author Bego
	 * 
	 * @param idEquipo
	 * @param usuario
	 * @param correo
	 * @return
	 */
	public int modificarUsuarioDesdeEquipo(int idEquipo, String usuario, String correo) {
		int res = -1;
		String strSQL = "UPDATE usuarios, equipo "
				+ "SET usuarios.nombre = '" + usuario +"'"
				+ ", usuarios.email='" + correo + "' "
				+ "WHERE usuarios.idUsuario = equipo.idUsuario "
				+ "AND equipo.idEquipo = " + idEquipo;
		try {
			res = Principal.BBDD.actualizar(strSQL);
		} catch (SQLException ex) {
			System.out.println("SQLException: " + ex.getMessage());
			System.out.println("SQLState: " + ex.getSQLState());
			System.out.println("VendorError: " + ex.getErrorCode());
		}

		return res;
	}

}
